﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Volo.Abp.Domain.Services;
using WorkFlowCore.Plugins;
using WorkFlowCore.UserSelectors;

namespace WorkFlowCore.Conditions
{
    public class ConditionManager : IDomainService
    {
        private readonly PluginManager pluginManager;


        public ConditionManager(PluginManager pluginManager)
        {
            this.pluginManager = pluginManager;
        }

        /// <summary>
        /// 所有条件
        /// </summary>
        public List<Condition> AllConditions
        {
            get
            {
                var result = new List<Condition>();
                var configs = pluginManager.GetPluginApplyConfigs(typeof(ICondition).FullName).Result;

                foreach (var config in configs.applyConfigs.OrderBy(c=>c.Order))
                {
                    var manifest = configs.manifests.Where(m=>m.ClassName==config.EntryFullName).FirstOrDefault();
                    if (manifest == null) continue;
                    result.Add(new Condition(config.PluginId, string.IsNullOrWhiteSpace(config.Name) ? manifest?.Name : config.Name, string.IsNullOrWhiteSpace(config.Description)? manifest.Description :config.Description, config?.Enabled ?? true));
                }
                return result;
            }
        }

        /// <summary>
        /// 获取转换器
        /// </summary>
        /// <returns></returns>
        public virtual ICondition GetCondition(string conditionId)
        {

            return pluginManager.Resolve<ICondition>(conditionId);
        }

        /// <summary>
        /// 从 程序集注册
        /// </summary>
        /// <param name="services"></param>
        /// <param name="assemblies"></param>
        public static void Registercondition(IServiceCollection services, params Assembly[] assemblies)
        {
            foreach (var assembly in assemblies)
            {
                var types = assembly.GetTypes().Where(t => typeof(ICondition).IsAssignableFrom(t));

                foreach (var type in types)
                {
                    var attr = type.GetCustomAttribute<ConditionAttribute>();
                    var conditionId = type.FullName;
                    var conditionName = attr?.Name ?? type.FullName;
                    services.AddScoped(type);

                    PluginManager.Register(new ManifestWithConfig(conditionId, conditionName,  attr?.Description, "", "default", assembly));
                }
            }
        }
    }
}
